﻿#define REALPLATFORM

using System;
using System.ComponentModel;
using System.IO.Ports;

namespace JD.IRCDIS.Instruction
{
        public class SerialPortInstruction : INotifyPropertyChanged
        {
                #region 构造函数

                public SerialPortInstruction()
                {
                        PortName = "COM1";
                }

                #endregion 构造函数

                #region 常量

                private const byte P = 0X0D;

                #endregion 常量

                #region 字段

                private String portName = null;

                #endregion 字段

                #region 属性

                public string PortName
                {
                        get
                        {
                                return portName;
                        }
                        set
                        {
                                if (portName != value)
                                {
                                        if (SerialPort != null)
                                        {
                                                SerialPort.Close();
                                        }

                                        portName = value;

                                        SerialPort = new SerialPort(portName);

                                        SerialPort.BaudRate = 9600;
                                        SerialPort.DataBits = 8;
                                        SerialPort.StopBits = StopBits.One;
                                        SerialPort.Parity = Parity.None;
                                        SerialPort.ReceivedBytesThreshold = 13;

                                        SerialPort.Open();

                                        OnPropertyChanged("PortName");
                                        OnPropertyChanged("SerialPortInfo");
                                }
                        }
                }

                /// <summary>
                /// 获取当前工作串口
                /// </summary>
                /// <value>当前工作串口</value>
                public SerialPort SerialPort { get; private set; }

                public string SerialPortInfo
                {
                        get
                        {
                                return "通讯端口：" + PortName + "  通讯状态：" + (SerialPort.IsOpen ? "正常" : "异常");
                        }
                }

                #endregion 属性

                #region 事件

                public event PropertyChangedEventHandler PropertyChanged;

                #endregion 事件

                #region 方法

                ///<summary>
                /// 串口通讯模式下控制器验证指令
                /// </summary>
                public void ValidateInstruction()
                {
                        Byte[] Instruction = new Byte[5] { 0XFF, 0X5F, P, 0X52, 0X6C };

                        SerialPort.Write(Instruction, 0, 5);
                }

                /// <summary>
                /// 获取串口通讯模式下双摄像机通电指令
                /// </summary>
                /// <param name="leftCameraId">左摄像机编号</param>
                /// <param name="rightCameraId">右摄像机编号</param>
                /// <returns>字节指令数组</returns>
                public void SendPowerInstruction(int leftCameraId, int rightCameraId)
                {
                        Byte[] command = new Byte[5];
                        command[0] = 0XFF;
                        command[1] = 0X5A;
                        command[2] = Convert.ToByte((1 << (leftCameraId - 1)) + (1 << (rightCameraId - 1)));
                        command[3] = Convert.ToByte((255 + command[1] + command[2]) % 255);
                        command[4] = Convert.ToByte(command[1] ^ command[2]);

                        SerialPort.Write(command, 0, command.Length);
                }

                /// <summary>
                /// 获取串口通讯模式下单摄像机通电指令
                /// </summary>
                /// <param name="cameraId">通电摄像机编号</param>
                /// <returns>字节指令数组</returns>
                public void SendPowerInstruction(int cameraId)
                {
                        Byte[] command = new Byte[5];
                        command[0] = 0XFF;
                        command[1] = 0X5A;
                        command[2] = Convert.ToByte(cameraId << 4);
                        command[3] = Convert.ToByte(command[1] + command[2]);
                        command[4] = Convert.ToByte(command[1] ^ command[2]);

                        SerialPort.Write(command, 0, command.Length);
                }

                /// <summary>
                /// 串口通讯模式下摄像机光圈调整指令
                /// </summary>
                /// <param name="cameraId">摄像机编号</param>
                /// <param name="isIncrease">为true光圈增大，为false光圈减小</param>
                /// <returns>字节指令数组</returns>
                public void SendApertureInstruction(int cameraId, bool isIncrease)
                {
                        Byte[] command = new Byte[5];
                        command[0] = 0XFF;
                        command[1] = 0X5C;
                        command[2] = Convert.ToByte((cameraId << 4) + (isIncrease ? 1 : 0));
                        command[3] = Convert.ToByte(command[1] + command[2]);
                        command[4] = Convert.ToByte(command[1] ^ command[2]);

                        SerialPort.Write(command, 0, command.Length);
                }

                /// <summary>
                /// 串口通讯模式下摄像机焦距调整指令
                /// </summary>
                /// <param name="cameraId">摄像机编号</param>
                /// <param name="isIncrease">为true焦距增大，为false焦距减小</param>
                /// <returns>字节指令数组</returns>
                public void SendFocalDistanceInstruction(int cameraId, bool isIncrease)
                {
                        Byte[] command = new Byte[5];
                        command[0] = 0XFF;
                        command[1] = 0X5D;
                        command[2] = Convert.ToByte((cameraId << 4) + (isIncrease ? 1 : 0));
                        command[3] = Convert.ToByte(command[1] + command[2]);
                        command[4] = Convert.ToByte(command[1] ^ command[2]);

                        SerialPort.Write(command, 0, command.Length);
                }

                /// <summary>
                /// 获取串口通讯模式下摄像机聚焦调整指令
                /// </summary>
                /// <param name="cameraId">摄像机编号</param>
                /// <param name="isIncrease">为true聚焦增大，为false聚焦减小</param>
                /// <returns>字节指令数组</returns>
                public void SendFocusInstruction(int cameraId, bool isIncrease)
                {
                        Byte[] command = new Byte[5];
                        command[0] = 0XFF;
                        command[1] = 0X5E;
                        command[2] = Convert.ToByte((cameraId << 4) + (isIncrease ? 1 : 0));
                        command[3] = Convert.ToByte(command[1] + command[2]);
                        command[4] = Convert.ToByte(command[1] ^ command[2]);

                        SerialPort.Write(command, 0, command.Length);
                }

                /// <summary>
                /// 串口通讯模式下摄像机光圈、聚焦、焦距调整幅度指令
                /// </summary>
                /// <param name="span">每次光圈聚焦、焦距、聚焦调整通电毫秒数</param>
                /// <returns>字节指令数组</returns>
                public void SendSpanInstruction(int span)
                {
                        Byte[] command = new Byte[5];
                        command[0] = 0XFF;
                        command[1] = 0X60;
                        command[2] = Convert.ToByte(span);
                        command[3] = Convert.ToByte(command[1] + command[2]);
                        command[4] = Convert.ToByte(command[1] ^ command[2]);

                        SerialPort.Write(command, 0, command.Length);
                }

                

                public void OnPropertyChanged(String propertyName)
                {
                        if (PropertyChanged != null)
                        {
                                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                        }
                }

                #endregion 方法
        }
}